package com.gopay.solution.domain.bo.impl;

import com.gopay.common.constants.poundage.FeeDtlStatus;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.poundage.PoundageReq;
import com.gopay.common.solution.util.CalculateFeeUtil;
import com.gopay.common.solution.vo.CacheFeeDtlInfo;
import com.gopay.solution.domain.po.SolutionRuleDtl;
import com.gopay.solution.domain.po.SsTransFeeDtl;
import com.gopay.solution.domain.vo.Event;
import com.gopay.solution.domain.vo.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

/**
 * 交易手续费方案规则执行器
 * 
 * @SsTransFeeSoluRuleExecutor.java
 * @author MA HUAN
 * @2013-3-27 下午2:58:56 www.gopay.com.cn Inc.All rights reserved.
 */

@Service(value = "ssTransFeeSoluRuleExecutor")
public class SsTransFeeSoluRuleExecutor extends AbstractSolutionRuleExecutor {

    @Override
    public Result execute(List<SolutionRuleDtl> rules, Event event) {

        Result res = new Result();
        res.setSolved(false);
        res.setFailedReason("");
        res.setDetail(null);

        if (null == rules || rules.isEmpty()) {
            res.setFailedReason("查询不到手续费方案记录");
            return res;
        }

        Serializable input = event.getDetail();

        PoundageReq req = (PoundageReq) input;
        String payChannel = req.getPayChannel();
        String acctType = req.getAcctType();
        IntTxnCd intTxnCd = req.getIntTxnCd();
        BigDecimal amt = req.getAmount();
        //update by jianghp 手续费方案修改
        String bankCode = req.getBankCode();//特例银行编码 可空
        String acctId = req.getAcctId(); //账户号
        boolean cacheFlag = req.getCacheFlag();//redis缓存标志位  默认为false
        String redisEnvironment = req.getRedisEnvironment();//环境变量 可空
        String prodCode = req.getProdCode();//账户类型 可空

        for (SolutionRuleDtl rule : rules) {
            SsTransFeeDtl feeDtl = (SsTransFeeDtl) rule;
            //在上面就设置邮电费
            BigDecimal postFee= feeDtl.getPostAmt();
            if(postFee==null||"".equals(postFee)){
                //没有邮电费
                res.setPostAmt("0.00");
            }else{
                res.setPostAmt(postFee);
            }
            //设置外卡支付的定额收费和拒付申诉费
            BigDecimal wkQuotaFeeAmt= feeDtl.getWkQuotaFeeAmt();
            if(wkQuotaFeeAmt==null||"".equals(wkQuotaFeeAmt)){
                //没有定额手续费
                res.setWkQuotaFeeAmt("0.00");
            }else{
                res.setWkQuotaFeeAmt(wkQuotaFeeAmt);
            }
            BigDecimal wkComplaintFeeAmt= feeDtl.getWkComplaintFeeAmt();
            if(wkComplaintFeeAmt==null||"".equals(wkComplaintFeeAmt)){
                //没有拒付申诉费
                res.setWkComplaintFeeAmt("0.00");
            }else{
                res.setWkComplaintFeeAmt(wkComplaintFeeAmt);
            }
            BigDecimal fee = null;
            //手续费明细转换
            if (StringUtils.equals(feeDtl.getAcctType(), acctType) && StringUtils.equals(feeDtl.getPayChannel(), payChannel)
                    && StringUtils.equals(feeDtl.getGopayIntTxnCd(), intTxnCd.value) && StringUtils.equals(feeDtl.getDtlStatus(), FeeDtlStatus._00.value)){
                CacheFeeDtlInfo  dtl = transferRule(feeDtl);
                fee = CalculateFeeUtil.amt(dtl, amt, payChannel, intTxnCd.value, acctType, bankCode, acctId, cacheFlag,redisEnvironment,prodCode);
            }
            if (null != fee) {
                res.setDetail(fee);
                break;
            }
        }

        if (null != res.getDetail()) {
            res.setSolved(true);
        }
        return res;
    }

    /**
     * 手续费明细转换 add by jianghoup
     */
    private CacheFeeDtlInfo transferRule(SsTransFeeDtl rule) {
        CacheFeeDtlInfo dtl = new CacheFeeDtlInfo();
        dtl.setGopayIntTxnCd(rule.getGopayIntTxnCd());
        dtl.setGatewaySource(rule.getGatewaySource());
        dtl.setPayChannel(rule.getPayChannel());
        dtl.setFeeType(rule.getFeeType());
        dtl.setCalExp(rule.getCalExp());
        dtl.setAcctType(rule.getAcctType());
        dtl.setRemarks(rule.getRemarks());
        dtl.setDtlStatus(rule.getDtlStatus());
        dtl.setSpecExp(rule.getSpecExp());
        dtl.setSpecType(rule.getSpecType());
        return dtl;
    }
}
